﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Office = Microsoft.Office.Core;
using System.Windows.Forms;

namespace SharedAddin
{
    /// <summary>
    /// This class mirrors the Office.CustomTaskPaneCollection
    /// </summary>
    public class SharedCustomTaskPaneCollection
    {
        // Public list of TaskPane items
        public List<SharedCustomTaskPane> Items = new List<SharedCustomTaskPane>();
        private Office.ICTPFactory _paneFactory;

        /// <summary>
        /// CTOR - takes the factor from the interface method
        /// </summary>
        /// <param name="CTPFactoryInst"></param>
        public SharedCustomTaskPaneCollection(Office.ICTPFactory CTPFactoryInst)
        {
            _paneFactory = CTPFactoryInst;
        }

        /// <summary>
        /// Adds a new TaskPane to the collection and takes a 
        /// User Form Control reference for the contents of the
        /// Control Pane
        /// </summary>
        /// <param name="control"></param>
        /// <param name="Title"></param>
        /// <returns></returns>
        public SharedCustomTaskPane Add(Control control, string Title)
        {
            // create a new Pane object
            SharedCustomTaskPane newPane = new SharedCustomTaskPane(control, Title, _paneFactory);
            Items.Add(newPane); // add it to the collection
            return newPane; // return a reference
        }

        /// <summary>
        /// Remove the specific pane from the list
        /// </summary>
        /// <param name="pane"></param>
        public void Remove(SharedCustomTaskPane pane)
        {
            Items.Remove(pane);
            pane.Dispose(); // dispose the pane
        }

        /// <summary>
        /// Get a list
        /// </summary>
        public int Count
        {
            get
            {
                return Items.Count;
            }
        }
    }

    /// <summary>
    /// This class mirrors the Office.CustomTaskPane class 
    /// </summary>
    public class SharedCustomTaskPane
    {
        private string _title = string.Empty;
        private Control _control = null;
        private Office.CustomTaskPane _taskPane;
        private BaseControl _base;
        public string Title { get { return _title; } }
        public event EventHandler VisibleChanged;

        /// <summary>
        /// Get or set the dock position of the TaskPane
        /// </summary>
        public Office.MsoCTPDockPosition DockPosition
        {
            get
            {
                return _taskPane.DockPosition;
            }
            set
            {
                _taskPane.DockPosition = value;
            }
        }

        /// <summary>
        /// Show or hide the CustomTaskPane
        /// </summary>
        public bool Visible
        {
            get
            {
                return _taskPane.Visible;
            }
            set
            {
                _taskPane.Visible = value;
            }
        }

        /// <summary>
        /// Reference to the control
        /// </summary>
        public Control Control { get { return _control; } }

        /// <summary>
        /// CTOR
        /// </summary>
        /// <param name="control"></param>
        /// <param name="Title"></param>
        /// <param name="CTPFactoryInst"></param>
        public SharedCustomTaskPane(Control control, string Title, Office.ICTPFactory CTPFactoryInst)
        {
            // create the taskpane control and use the factory to create a new instance of
            // our base control "CustomTaskPaneControl.BaseControl"
            _control = control;
            _title = Title;
            _taskPane = CTPFactoryInst.CreateCTP("CustomTaskPaneControl.BaseControl", Title);
            _taskPane.Width = control.Width + 2;
            _base = (BaseControl)_taskPane.ContentControl;
            _base.ChildControls.Add(control);
            _base.Height = control.Height + 2;
            // when the visibility changes fire an event
            _taskPane.VisibleStateChange += (Office.CustomTaskPane CustomTaskPaneInst) =>
            {
                VisibleChanged(this, new EventArgs());
            };
        }

        /// <summary>
        /// Dispose of the control and collect
        /// </summary>
        public void Dispose()
        {
            try
            {
                _taskPane.Visible = false;
            }
            catch { }
            try
            {
                _control.Dispose();
                _control = null;
                _base.Dispose();
                _base = null;
            }
            catch { }
            GC.Collect();
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
    }
}
